package cn.org.xwb.bookmall.model.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.org.xwb.bookmall.model.constant.AccountConst;
import cn.org.xwb.bookmall.model.po.AllowMail;
import cn.org.xwb.bookmall.model.mapper.AllowMailMapper;
import cn.org.xwb.bookmall.model.service.IAllowMailService;
import cn.org.xwb.bookmall.model.utils.BookRedisUtil;
import cn.org.xwb.common.page.dto.PageResult;
import cn.org.xwb.common.redis.utils.RedisUtil;
import cn.org.xwb.common.page.utils.PageUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 允许登录管理端的邮箱 服务实现类
 * </p>
 *
 * @author xwb
 * @since 2023-11-23
 */
@Service
public class AllowMailServiceImpl extends ServiceImpl<AllowMailMapper, AllowMail> implements IAllowMailService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BookRedisUtil bookRedisUtil;

    /**
     * 获取 redis 中 allow mails 对应的 key
     *
     * @return
     */
    private String getKeyAllowMails() {
        return bookRedisUtil.getRedisKeyAdmin(AccountConst.ALLOW_MAILS, "");
    }


    /**
     * 查询并缓存所有允许登录管理端的邮箱（包括禁用的）
     *
     * @return null-发生异常
     *         List<AllowMail>-成功
     */
    @Override
    public List<AllowMail> findAndCacheAll() {
        // 查询所有允许登录管理端的邮箱
        List<AllowMail> allowMails = baseMapper.selectAll();
        // 缓存
        Boolean res = redisUtil.setList(getKeyAllowMails(), allowMails);
        if (!res) return null;
        return allowMails;
    }

    /**
     * 从缓存中查询所有允许登录管理端的邮箱（包括禁用的），
     * 如果缓存中不存在，则从数据库中查询，并缓存
     *
     * @return null-发生异常
     */
    @Override
    public List<AllowMail> findAllFromCache() {
        // 从缓存中查询
        List<AllowMail> allowMails = (List<AllowMail>) redisUtil.get(getKeyAllowMails());
        // 缓存中不存在，从数据库中查询，并缓存
        if (Objects.isNull(allowMails)) allowMails = findAndCacheAll();
        // 发生异常
        if (Objects.isNull(allowMails)) return null;
        // 获取成功
        return allowMails;
    }

    /**
     * 分页获取允许登录的邮箱
     *
     * @param current 第几页
     * @param pageSize 每页数据个数
     * @param disabled 是否禁用的邮箱
     * @param match 模糊匹配条件
     * @return null-发生异常
     */
    @Override
    public PageResult<List<AllowMail>> findAllowMailsPage(Integer current, Integer pageSize, Boolean disabled, String match) {
        // 获取全部的数据
        List<AllowMail> allowMails = findAllFromCache();
        if (Objects.isNull(allowMails)) return null;
        // 有条件就过滤
        if (Objects.nonNull(disabled)) {
            allowMails = allowMails.stream().filter(allowMail -> allowMail.getDisabled() == disabled).toList();
        }
        if (Objects.nonNull(match) && !match.isEmpty()) {
            allowMails = allowMails.stream().filter(allowMail -> allowMail.getMail().contains(match)).toList();
        }
        // 页数
        Integer pageCnt = PageUtil.getPageCnt(allowMails.size(), pageSize);
        // 分页数据
        allowMails = ((List<AllowMail>) PageUtil.getPageData(allowMails, current, pageSize));
        return new PageResult<List<AllowMail>>(current, pageSize, allowMails.size(), pageCnt, allowMails);
    }

    /**
     * 判断邮箱是否允许登录管理端
     *
     * @param mail
     * @return null-发生异常，true-允许；false-不允许
     */
    @Override
    public Boolean judgeAllow(String mail) {
        // 从缓存中查询
        List<AllowMail> allowMails = (List<AllowMail>) redisUtil.get(bookRedisUtil.getRedisKeyAdmin(AccountConst.ALLOW_MAILS, ""));
        // 缓存中不存在，从数据库中查询并缓存
        if (Objects.isNull(allowMails)) allowMails = findAndCacheAll();
        // 依旧是空，发生异常
        if (Objects.isNull(allowMails)) return null;
        // 判断邮箱是否允许登录管理端
        // 存在没有禁用的，且邮箱相等，则可以登录
        return allowMails.stream().anyMatch(
                item -> !item.getDisabled() && item.getMail().equals(mail)
        );
    }
}
